package com.cfwx.util.encryption;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.log4j.Logger;

/**
 * MD5加密类.
 * 
 * @author luoyz
 * 
 */
public class MD5 {
	/**
	 * 日志对象.
	 */
	private static Logger logger = Logger.getLogger(MD5.class);

	/**
	 * 私有构造函数.
	 */
	private MD5() {
	}

	/**
	 * 返回plainText的MD5值.
	 * 
	 * @param plainText
	 *            一个需要MD5的字符串.
	 * @return 返回plainText的MD5值.
	 */
	public static String md5s(String plainText) {
		String result = null;

		if (plainText == null) {
			return null;
		}

		byte[] byteArray = null;
		byte b[] = null;
		int i;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byteArray = plainText.getBytes("GBK");
			md.update(byteArray);
			b = md.digest();

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0) {
					i += 256;
				}
				if (i < 16) {
					buf.append("0");
				}
				buf.append(Integer.toHexString(i));
			}
			result = buf.toString();
		} catch (Exception e) {
			logger.error("MD5.MD5s error!", e);
		}

		return result;
	}

	/**
	 * 计算文件的MD5.
	 * 
	 * @param file
	 *            需要计算 MD5的File对象.
	 * @return 成功则 返回 MD5字符串, 失败返回 null.
	 */
	public static String getMD5(File file) {
		FileInputStream fis = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			fis = new FileInputStream(file);
			byte[] buffer = new byte[8192];
			int length = -1;
			while ((length = fis.read(buffer)) != -1) {
				md.update(buffer, 0, length);
			}
			return bytesToString(md.digest());
		} catch (IOException ex) {
			logger.error("", ex);
			return null;
		} catch (NoSuchAlgorithmException ex) {
			logger.error("", ex);
			return null;
		} finally {
			try {
				fis.close();
			} catch (IOException ex) {
				logger.error("", ex);
			}
		}
	}

	/**
	 * 将byte[]转换成16进制字符串.
	 * 
	 * @param data
	 *            待转换byte[].
	 * @return byte[]转换成的16进制字符串.
	 */	
	public static String bytesToString(byte[] data) {
		if (data == null) {
			return "";
		}

		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };
		char[] temp = new char[data.length * 2];
		for (int i = 0; i < data.length; i++) {
			byte b = data[i];
			temp[i * 2] = hexDigits[b >>> 4 & 0x0f];
			temp[i * 2 + 1] = hexDigits[b & 0x0f];
		}
		
		return new String(temp);
	}
}
